/*
 *    Copyright (c) 2018-2025, proj All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the proj developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: proj
 */
package com.ykht.proj.activity.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ykht.proj.activity.constant.CardConstant;
import com.ykht.proj.activity.entity.*;
import com.ykht.proj.activity.mapper.VDiscountPlanMapper;
import com.ykht.proj.activity.service.VDiscountPlanService;
import com.ykht.proj.activity.service.VDiscountPlanShopService;
import com.ykht.proj.activity.vo.*;
import com.ykht.proj.common.core.util.R;
import com.ykht.proj.common.security.util.SecurityUtils;
import com.ykht.proj.coupon.api.feign.RemoteShopService;
import com.ykht.proj.coupon.vo.CnShopDisVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 优惠方案表
 *
 * @author csg
 * @date 2021-05-18 14:26:34
 */
@RequiredArgsConstructor
@Slf4j
@Service
public class VDiscountPlanServiceImpl extends ServiceImpl<VDiscountPlanMapper, VDiscountPlan> implements VDiscountPlanService {

	private final VDiscountPlanMapper vDiscountPlanMapper;

	/**
	 * 优惠方案和门店关联表 Api  服务
	 */
	private final VDiscountPlanShopService vDiscountPlanShopService;
	private final RemoteShopService remoteShopService;

	/**
	 * 新增优惠方案表，并添加门店列表
	 *
	 * @param vDiscountPlanVo
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void addVDiscountPlan(VDiscountPlanVo vDiscountPlanVo) {
		Long userId = SecurityUtils.getUserId();
		vDiscountPlanVo.setCreateUser(userId);
		vDiscountPlanVo.setCreateTime(LocalDateTime.now());
		VDiscountPlan vDiscountPlan = BeanUtil.toBean(vDiscountPlanVo, VDiscountPlan.class);
		this.save(vDiscountPlan);
		List<VDiscountPlanShop> planShopList = new ArrayList<>();
		vDiscountPlanVo.getSjObjectList().stream().forEach(itme -> {
			VDiscountPlanShop vDiscountPlanShop = new VDiscountPlanShop();
			vDiscountPlanShop.setDiscountPlanId(vDiscountPlan.getId());
			vDiscountPlanShop.setShopId(itme.getShopId());
			vDiscountPlanShop.setBrandId(itme.getBrandId());
			vDiscountPlanShop.setCompanyId(itme.getCompanyId());
			vDiscountPlanShop.setCreateUser(userId);
			vDiscountPlanShop.setCreateTime(LocalDateTime.now());
			planShopList.add(vDiscountPlanShop);
		});
		vDiscountPlanShopService.saveBatch(planShopList);
	}


	/**
	 * 修改优惠方案表
	 *
	 * @param vDiscountPlanVo
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateVDiscountPlan(VDiscountPlanVo vDiscountPlanVo) {
		Long userId = SecurityUtils.getUserId();
		vDiscountPlanVo.setUpdateUser(userId);
		vDiscountPlanVo.setUpdateTime(LocalDateTime.now());
		VDiscountPlan vDiscountPlan = BeanUtil.toBean(vDiscountPlanVo, VDiscountPlan.class);
		this.updateById(vDiscountPlan);
		vDiscountPlanShopService.remove(Wrappers.lambdaQuery(VDiscountPlanShop.class)
				.eq(VDiscountPlanShop::getDiscountPlanId, vDiscountPlanVo.getId()));
		List<VDiscountPlanShop> planShopList = new ArrayList<>();
		vDiscountPlanVo.getSjObjectList().stream().forEach(itme -> {
			VDiscountPlanShop vDiscountPlanShop = new VDiscountPlanShop();
			vDiscountPlanShop.setDiscountPlanId(vDiscountPlan.getId());
			vDiscountPlanShop.setShopId(itme.getShopId());
			vDiscountPlanShop.setBrandId(itme.getBrandId());
			vDiscountPlanShop.setCompanyId(itme.getCompanyId());
			vDiscountPlanShop.setCreateUser(userId);
			vDiscountPlanShop.setCreateTime(LocalDateTime.now());
			planShopList.add(vDiscountPlanShop);
		});
		vDiscountPlanShopService.saveBatch(planShopList);
	}

	/**
	 * 创建群组取门店列表（根据品牌标签, 品牌/门店名, 地址查询,协议类型)
	 *
	 * @param cnGroupShopVoReq
	 * @return
	 */
	@Override
	public Page<CnGroupShopVoReq> getByGroupShop(Page page, CnGroupShopVoReq cnGroupShopVoReq) {
		return vDiscountPlanMapper.getByGroupShop(page, cnGroupShopVoReq);
	}

	/**
	 * 优惠方案 分页查询
	 *
	 * @param page            分页
	 * @param vDiscountPlanVo 条件
	 * @return
	 */
	@Override
	public IPage<VDiscountPlanVo> getVDiscountPlanPage(Page page, VDiscountPlanVo vDiscountPlanVo) {
		return vDiscountPlanMapper.getVDiscountPlanPage(page, vDiscountPlanVo);
	}

	/**
	 * 通过id删除优惠方案表
	 *
	 * @param id
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteDiscountPlan(Long id) {
		this.removeById(id);
		vDiscountPlanShopService.remove(Wrappers.lambdaQuery(VDiscountPlanShop.class)
				.eq(VDiscountPlanShop::getDiscountPlanId, id));
	}

	/**
	 * 根据协议ID获取  协议和公司详情
	 *
	 * @param id
	 * @return
	 */
	@Override
	public VDiscountPlanVo getByIdDiscountPlan(Long id) {
		return vDiscountPlanMapper.getByIdDiscountPlan(id);
	}

	@Override
	public List<VPlanInfo> getPlanInfo(VPlanInfoReq req) {
		return vDiscountPlanMapper.getPlanInfo(req);
	}

	@Override
	public BigDecimal minDiscount(VCard card, VOrderCard orderCard) {
		BigDecimal dis =BigDecimal.TEN;
		List<Long> shopIds = new ArrayList<>();
		VPlanInfoReq vPlanInfoReq = new VPlanInfoReq();

		if (CardConstant.DISCOUNT_TYPE_BF==card.getDiscountType()){
			shopIds = new VOrderCardShop().selectList(Wrappers.lambdaQuery(VOrderCardShop.class)
					.select(VOrderCardShop::getShopId).eq(VOrderCardShop::getOrderCardId, orderCard.getId()))
					.stream().map(VOrderCardShop::getShopId).collect(Collectors.toList());
		}else {
			List<Long> groups = new VCardGroup().selectList(Wrappers.lambdaQuery(VCardGroup.class).eq(VCardGroup::getCardId,card.getId())).stream().map(VCardGroup::getGroupId).collect(Collectors.toList());
			log.info("--->获取可选门店");
			if (groups.size()==0) throw new RuntimeException("卡未关联群组");
			shopIds = new VGroupShop().selectList(Wrappers.lambdaQuery(VGroupShop.class).select(VGroupShop::getShopId).in(VGroupShop::getGroupId, groups)).stream().map(VGroupShop::getShopId).collect(Collectors.toList());
		}

		//门店为维度的所有的优惠方案
		log.info("--->获取最低折扣");
		List<VPlanInfo> vPlanInfoList = this.getPlanInfo(new VPlanInfoReq(shopIds));

			switch (card.getPriceType()){
				case 2:
					//取优
					return vPlanInfoList.stream()
							.sorted(Comparator.comparing(oo->oo.getDp().getDiscount()))
							.map(oo->oo.getDp().getDiscount()).findFirst().get();
				default:
					//门店一至并且卡的价格类型一直
					return vPlanInfoList.stream().filter(oo->oo.getDp().getPlanType().equals(card.getPriceType()))
							.sorted(Comparator.comparing(oo->oo.getDp().getDiscount()))
							.map(oo->oo.getDp().getDiscount()).findFirst().get();
			}
	}


	//转换数据格式
	@Override
	public List<CardPlanInfo> getCardPlanInfo(List<CardShopVo> cardShopVoList, List<CnShopDisVo> shopDisVoList) {
		if (shopDisVoList.size()==0) shopDisVoList = new ArrayList<>();
		if (cardShopVoList.size()==0) cardShopVoList = new ArrayList<>();
		Set<Long> shopIds = new HashSet<>();
		Set<Long> cardIds = new HashSet<>();

		cardShopVoList.stream().forEach(o->{
			shopIds.add(o.getShopId());
			cardIds.add(o.getCardId());
		});
		List<VCard> cardList = new ArrayList<>();
		if (cardIds.size()>0) cardList = new VCard().selectList(Wrappers.lambdaQuery(VCard.class).in(VCard::getId,cardIds));
		//所有门店优惠方案
		List<VPlanInfo> planInfoList = this.getPlanInfo(new VPlanInfoReq(ListUtil.toList(shopIds)));

		List<ShopPlan> planInfoListTemp =  this.planInfoTransform2ShopPlan(planInfoList,shopDisVoList);

		Map<Long,List<Long>> card2ShopIds = cardShopVoList.stream().collect(Collectors.groupingBy(CardShopVo::getCardId,Collectors.mapping(CardShopVo::getShopId, Collectors.toList())));

		List<VCard> finalCardList = cardList;

		List<CardPlanInfo> list = new ArrayList<>();
		card2ShopIds.forEach((k,v)->{
			CardPlanInfo cardPlanInfo = new CardPlanInfo();
			finalCardList.stream().filter(oo->oo.getId().equals(k)).findFirst().ifPresent(oo->cardPlanInfo.setCard(oo));
			if (null != cardPlanInfo.getCard().getId()) {
				List<ShopPlan> shopPlanList = new ArrayList<>();
				//价格类型  0企业价  1活动价 2企业价与活动价取优
				switch (cardPlanInfo.getCard().getPriceType()){
					case 2:
						//取优
						v.stream().forEach(oo->{
							planInfoListTemp.stream().filter(ooo->ooo.getInfo().getDps().getShopId().equals(oo))
									.sorted(Comparator.comparing((ShopPlan ooo)->ooo.getInfo().getDp().getDiscount())).findFirst().ifPresent(ooo->shopPlanList.add(ooo));
						});
						break;
					default:
						//门店一至并且卡的价格类型一直
						v.stream().forEach(oo-> planInfoListTemp.stream().filter(ooo->ooo.getInfo().getDps().getShopId().equals(oo)
								&&cardPlanInfo.getCard().getPriceType().equals(ooo.getInfo().getDp().getPlanType())).findFirst().ifPresent(ooo->shopPlanList.add(ooo)));
						break;
				}
				cardPlanInfo.setShopPlanList(shopPlanList);
				list.add(cardPlanInfo);
			}
		});
		return list;
	}
	@Override
	public List<ShopPlan> planInfoTransform2ShopPlan(List<VPlanInfo> planInfoList, List<CnShopDisVo> shopDisVoList) {
		List<ShopPlan> planInfoListTemp = planInfoList.stream().map(oo->{
			ShopPlan shopPlan = new ShopPlan();
			shopDisVoList.stream().filter(ooo->ooo.getId().equals(oo.getDps().getShopId())).findFirst().ifPresent(ooo->{
				ShopInfo shopInfo = BeanUtil.toBean(ooo,ShopInfo.class);
				if(ooo.getBrandLabel()!=null) shopInfo.setLabelName(ooo.getBrandLabel().getLabelName());
				shopPlan.setShopInfo(shopInfo);
			});
			shopPlan.setInfo(oo);
			return shopPlan;
		}).collect(Collectors.toList());
		return planInfoListTemp;
	}

}
